<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="utf-8">
  

  
  <title>Spring-secrity-rememberme-annotaion | Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="”记住我“是持久登录认证，应用程序会记住会话用户的身份，在登录时当你使用“记住我”的功能时，应用程序将会将一个cookie在登录成功后发送到浏览器。这个cookie将被保存到浏览器，并继续在一定期限（由cookie生命周期时间定义）.下一次，当您再次访问程序时，浏览器将检测到的cookie,那么用户就会自动登录，无需提供用户名和密码。">
<meta name="keywords" content="spring-secrity">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring-secrity-rememberme-annotaion">
<meta property="og:url" content="http://yoursite.com/2018/10/12/2018-01-21-Spring-secrity-rememberme-annotaion/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="”记住我“是持久登录认证，应用程序会记住会话用户的身份，在登录时当你使用“记住我”的功能时，应用程序将会将一个cookie在登录成功后发送到浏览器。这个cookie将被保存到浏览器，并继续在一定期限（由cookie生命周期时间定义）.下一次，当您再次访问程序时，浏览器将检测到的cookie,那么用户就会自动登录，无需提供用户名和密码。">
<meta property="og:locale" content="default">
<meta property="og:image" content="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104211045.png">
<meta property="og:image" content="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104215329.png">
<meta property="og:image" content="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104215306.png">
<meta property="og:image" content="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104215934.png">
<meta property="og:image" content="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104220056.png">
<meta property="og:image" content="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104220206.png">
<meta property="og:updated_time" content="2018-11-01T14:24:04.918Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Spring-secrity-rememberme-annotaion">
<meta name="twitter:description" content="”记住我“是持久登录认证，应用程序会记住会话用户的身份，在登录时当你使用“记住我”的功能时，应用程序将会将一个cookie在登录成功后发送到浏览器。这个cookie将被保存到浏览器，并继续在一定期限（由cookie生命周期时间定义）.下一次，当您再次访问程序时，浏览器将检测到的cookie,那么用户就会自动登录，无需提供用户名和密码。">
<meta name="twitter:image" content="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104211045.png">
  
    <link rel="alternate" href="/org/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/org/css/style.css">
</head>
</html>
<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/org/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/org/">Home</a>
        
          <a class="main-nav-link" href="/org/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/org/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-2018-01-21-Spring-secrity-rememberme-annotaion" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/org/2018/10/12/2018-01-21-Spring-secrity-rememberme-annotaion/" class="article-date">
  <time datetime="2018-10-12T09:03:30.000Z" itemprop="datePublished">2018-10-12</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      Spring-secrity-rememberme-annotaion
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>”记住我“是持久登录认证，应用程序会记住会话用户的身份，在登录时当你使用“记住我”的功能时，应用程序将会将一个cookie在登录成功后发送到浏览器。这个cookie将被保存到浏览器，并继续在一定期限（由cookie生命周期时间定义）.下一次，当您再次访问程序时，浏览器将检测到的cookie,那么用户就会自动登录，无需提供用户名和密码。</p>
<a id="more"></a>
<p>SpringSecrity提供了两种”记住我”的实现：</p>
<ul>
<li>简单基于散列标记的方法：它使用散列来保护基于cookie标记的安全性</li>
<li>持久化标记方法：它使用一个数据库或其他持久化存储机制来保存生成的标记</li>
</ul>
<p>今天教程中，我们将讨论用于持久化标记的方法</p>
<p>持久化标记方法，数据库中添加了一个名为 “persistent_logins ”表，可以创建使用下面的sql:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE persistent_logins (</span><br><span class="line">    username VARCHAR(64) NOT NULL,</span><br><span class="line">    series VARCHAR(64) NOT NULL,</span><br><span class="line">    token VARCHAR(64) NOT NULL,</span><br><span class="line">    last_used TIMESTAMP NOT NULL,</span><br><span class="line">    PRIMARY KEY (series)</span><br><span class="line">);</span><br></pre></td></tr></table></figure>
<p>此表包含用户名，“记住我”的最后一次活动时间(last_used时间戳)，Bcrypt内部实现安全令牌和一系列信息</p>
<p>在springSecrity中设置 “记住我”</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--场景：--&gt;</span><br><span class="line">&lt;!--http://localhost:8080/j_spring_security_check--&gt;</span><br><span class="line">&lt;!--使用spring-security框架，自定义login页面时，发现上面的请求404--&gt;</span><br><span class="line">&lt;!--原因：--&gt;</span><br><span class="line"></span><br><span class="line">&lt;!--spring-security的版本问题，spring-security4.x版本，若需要自定义login页面时，需要自定login-processing-url=“/j_spring_security_check”--&gt;</span><br><span class="line">&lt;!--spring-security3.x版本，不需要手动加--&gt;</span><br><span class="line">&lt;!--解决：--&gt;</span><br><span class="line"></span><br><span class="line">&lt;!--application-security.xml中加login-processing-url=“/j_spring_security_check”--&gt;</span><br><span class="line"></span><br><span class="line">&lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;</span><br><span class="line">             xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;</span><br><span class="line">             xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><br><span class="line">             xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd</span><br><span class="line">    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd&quot;&gt;</span><br><span class="line"></span><br><span class="line">    &lt;http auto-config=&quot;true&quot;&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/&quot; access=&quot;permitAll&quot;/&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/home&quot; access=&quot;permitAll&quot;/&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/admin**&quot; access=&quot;hasRole(&apos;ADMIN&apos;)&quot;/&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/dba**&quot; access=&quot;hasRole(&apos;ADMIN&apos;) and hasRole(&apos;DBA&apos;)&quot;/&gt;</span><br><span class="line">        &lt;form-login login-page=&quot;/login&quot;</span><br><span class="line">                    username-parameter=&quot;ssoId&quot;</span><br><span class="line">                    password-parameter=&quot;password&quot;</span><br><span class="line">                    authentication-failure-url=&quot;/Access_Denied&quot;</span><br><span class="line">                    /&gt;</span><br><span class="line">        &lt;csrf/&gt;</span><br><span class="line"></span><br><span class="line">        &lt;remember-me</span><br><span class="line">                remember-me-parameter=&quot;remember-me&quot;</span><br><span class="line">                remember-me-cookie=&quot;remember-me&quot;</span><br><span class="line">                token-validity-seconds=&quot;86400&quot;</span><br><span class="line">                data-source-ref=&quot;dataSource&quot; /&gt;</span><br><span class="line">    &lt;/http&gt;</span><br><span class="line"></span><br><span class="line">    &lt;authentication-manager &gt;</span><br><span class="line">        &lt;authentication-provider user-service-ref=&quot;customUserDetailsService&quot;&gt;</span><br><span class="line"></span><br><span class="line">        &lt;/authentication-provider&gt;</span><br><span class="line"></span><br><span class="line">    &lt;/authentication-manager&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &lt;beans:bean id=&quot;customUserDetailsService&quot; class=&quot;com.anlu.secrity.service.impl.CustomUserDetailsService&quot; /&gt;</span><br><span class="line"></span><br><span class="line">&lt;/beans:beans&gt;</span><br></pre></td></tr></table></figure>
<p>完整的代码示例：</p>
<p>需要使用到以下技术：</p>
<ul>
<li>Spring 4.1.6.RELEASE</li>
<li>Spring Security 4.0.1.RELEASE</li>
<li>Hibernate 4.3.6.Final</li>
<li>MySQL Server 5.6</li>
<li>Maven 3</li>
<li>JDK 1.7</li>
<li>Tomcat 8.0.21</li>
<li>Idea</li>
</ul>
<h4 id="第1步-工程目录结构"><a href="#第1步-工程目录结构" class="headerlink" title="第1步: 工程目录结构"></a>第1步: 工程目录结构</h4><p><img src="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104211045.png" alt="2"></p>
<h4 id="第2步：更新-pom-xml-以包括所需的相关性"><a href="#第2步：更新-pom-xml-以包括所需的相关性" class="headerlink" title="第2步：更新 pom.xml 以包括所需的相关性"></a>第2步：更新 pom.xml 以包括所需的相关性</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br></pre></td><td class="code"><pre><span class="line">&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><br><span class="line">  xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;</span><br><span class="line">  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;</span><br><span class="line">  &lt;groupId&gt;com.anlu.secrity&lt;/groupId&gt;</span><br><span class="line">  &lt;artifactId&gt;spring-secrity-rememberme&lt;/artifactId&gt;</span><br><span class="line">  &lt;packaging&gt;war&lt;/packaging&gt;</span><br><span class="line">  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;</span><br><span class="line">  &lt;name&gt;spring-secrity-rememberme Maven Webapp&lt;/name&gt;</span><br><span class="line">  &lt;url&gt;http://maven.apache.org&lt;/url&gt;</span><br><span class="line">  &lt;properties&gt;</span><br><span class="line">    &lt;springframework.version&gt;4.1.6.RELEASE&lt;/springframework.version&gt;</span><br><span class="line">    &lt;springsecurity.version&gt;4.0.1.RELEASE&lt;/springsecurity.version&gt;</span><br><span class="line">    &lt;hibernate.version&gt;4.3.6.Final&lt;/hibernate.version&gt;</span><br><span class="line">    &lt;mysql.connector.version&gt;5.1.31&lt;/mysql.connector.version&gt;</span><br><span class="line">  &lt;/properties&gt;</span><br><span class="line"></span><br><span class="line">  &lt;dependencies&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- Spring --&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-core&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springframework.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-web&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springframework.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springframework.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springframework.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-orm&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springframework.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &lt;!-- Spring Security --&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-security-web&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springsecurity.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-security-config&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springsecurity.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;spring-security-taglibs&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;springsecurity.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- Hibernate --&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.hibernate&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;hibernate-core&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;hibernate.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;!-- jsr303 validation --&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;javax.validation&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;validation-api&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;1.1.0.Final&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;!-- Hibernate validators --&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;org.hibernate&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;5.1.3.Final&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- MySQL --&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;mysql&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;$&#123;mysql.connector.version&#125;&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;javax.servlet-api&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;3.1.0&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;javax.servlet.jsp&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;javax.servlet.jsp-api&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;2.3.1&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;jstl&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;1.2&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">    &lt;dependency&gt;</span><br><span class="line">      &lt;groupId&gt;commons-fileupload&lt;/groupId&gt;</span><br><span class="line">      &lt;artifactId&gt;commons-fileupload&lt;/artifactId&gt;</span><br><span class="line">      &lt;version&gt;1.3.1&lt;/version&gt;</span><br><span class="line">    &lt;/dependency&gt;</span><br><span class="line">  &lt;/dependencies&gt;</span><br><span class="line">  &lt;build&gt;</span><br><span class="line">    &lt;finalName&gt;spring-secrity-rememberme&lt;/finalName&gt;</span><br><span class="line">  &lt;/build&gt;</span><br><span class="line">&lt;/project&gt;</span><br></pre></td></tr></table></figure>
<h2 id="数据库表部分"><a href="#数据库表部分" class="headerlink" title="数据库表部分"></a>数据库表部分</h2><h4 id="第3步：创建数据库模式并填充数据"><a href="#第3步：创建数据库模式并填充数据" class="headerlink" title="第3步：创建数据库模式并填充数据"></a>第3步：创建数据库模式并填充数据</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line">/* For Remember-Me token storage purpose */</span><br><span class="line">CREATE TABLE persistent_logins (</span><br><span class="line">    username VARCHAR(64) NOT NULL,</span><br><span class="line">    series VARCHAR(64) NOT NULL,</span><br><span class="line">    token VARCHAR(64) NOT NULL,</span><br><span class="line">    last_used TIMESTAMP NOT NULL,</span><br><span class="line">    PRIMARY KEY (series)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">/*All User&apos;s gets stored in APP_USER table*/</span><br><span class="line">create table APP_USER (</span><br><span class="line">   id BIGINT NOT NULL AUTO_INCREMENT,</span><br><span class="line">   sso_id VARCHAR(30) NOT NULL,</span><br><span class="line">   password VARCHAR(100) NOT NULL,</span><br><span class="line">   first_name VARCHAR(30) NOT NULL,</span><br><span class="line">   last_name  VARCHAR(30) NOT NULL,</span><br><span class="line">   email VARCHAR(30) NOT NULL,</span><br><span class="line">   state VARCHAR(30) NOT NULL, 	</span><br><span class="line">   PRIMARY KEY (id),</span><br><span class="line">   UNIQUE (sso_id)</span><br><span class="line">);</span><br><span class="line"> </span><br><span class="line">/* USER_PROFILE table contains all possible roles */  </span><br><span class="line">create table USER_PROFILE(</span><br><span class="line">   id BIGINT NOT NULL AUTO_INCREMENT,</span><br><span class="line">   type VARCHAR(30) NOT NULL,</span><br><span class="line">   PRIMARY KEY (id),</span><br><span class="line">   UNIQUE (type)</span><br><span class="line">);</span><br><span class="line"> </span><br><span class="line">/* JOIN TABLE for MANY-TO-MANY relationship*/   </span><br><span class="line">CREATE TABLE APP_USER_USER_PROFILE (</span><br><span class="line">    user_id BIGINT NOT NULL,</span><br><span class="line">    user_profile_id BIGINT NOT NULL,</span><br><span class="line">    PRIMARY KEY (user_id, user_profile_id),</span><br><span class="line">    CONSTRAINT FK_APP_USER FOREIGN KEY (user_id) REFERENCES APP_USER (id),</span><br><span class="line">    CONSTRAINT FK_USER_PROFILE FOREIGN KEY (user_profile_id) REFERENCES USER_PROFILE (id)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">/* Populate USER_PROFILE Table */</span><br><span class="line">INSERT INTO USER_PROFILE(type)</span><br><span class="line">VALUES (&apos;USER&apos;);</span><br><span class="line"></span><br><span class="line">INSERT INTO USER_PROFILE(type)</span><br><span class="line">VALUES (&apos;ADMIN&apos;);</span><br><span class="line"></span><br><span class="line">INSERT INTO USER_PROFILE(type)</span><br><span class="line">VALUES (&apos;DBA&apos;);</span><br><span class="line"></span><br><span class="line">/* Populate one Admin User. We need only one user to demonstrate this example. You can add more as done in previous posts*/</span><br><span class="line">INSERT INTO APP_USER(sso_id, password, first_name, last_name, email, state)</span><br><span class="line">VALUES (&apos;sam&apos;,&apos;abc125&apos;, &apos;Sam&apos;,&apos;Smith&apos;,&apos;samy@xyz.com&apos;, &apos;Active&apos;);</span><br><span class="line"></span><br><span class="line">/* Populate JOIN Table */</span><br><span class="line">INSERT INTO APP_USER_USER_PROFILE (user_id, user_profile_id)</span><br><span class="line">  SELECT user.id, profile.id FROM app_user user, user_profile profile</span><br><span class="line">  where user.sso_id=&apos;sam&apos; and profile.type=&apos;ADMIN&apos;;</span><br></pre></td></tr></table></figure>
<h2 id="安全部分"><a href="#安全部分" class="headerlink" title="安全部分"></a>安全部分</h2><h3 id="第4步：添加-Spring-Security配置文件"><a href="#第4步：添加-Spring-Security配置文件" class="headerlink" title="第4步：添加 Spring-Security配置文件"></a>第4步：添加 Spring-Security配置文件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--场景：--&gt;</span><br><span class="line">&lt;!--http://localhost:8080/j_spring_security_check--&gt;</span><br><span class="line">&lt;!--使用spring-security框架，自定义login页面时，发现上面的请求404--&gt;</span><br><span class="line">&lt;!--原因：--&gt;</span><br><span class="line"></span><br><span class="line">&lt;!--spring-security的版本问题，spring-security4.x版本，若需要自定义login页面时，需要自定login-processing-url=“/j_spring_security_check”--&gt;</span><br><span class="line">&lt;!--spring-security3.x版本，不需要手动加--&gt;</span><br><span class="line">&lt;!--解决：--&gt;</span><br><span class="line"></span><br><span class="line">&lt;!--application-security.xml中加login-processing-url=“/j_spring_security_check”--&gt;</span><br><span class="line"></span><br><span class="line">&lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;</span><br><span class="line">             xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;</span><br><span class="line">             xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><br><span class="line">             xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd</span><br><span class="line">    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd&quot;&gt;</span><br><span class="line"></span><br><span class="line">    &lt;http auto-config=&quot;true&quot;&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/&quot; access=&quot;permitAll&quot;/&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/home&quot; access=&quot;permitAll&quot;/&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/admin**&quot; access=&quot;hasRole(&apos;ADMIN&apos;)&quot;/&gt;</span><br><span class="line">        &lt;intercept-url pattern=&quot;/dba**&quot; access=&quot;hasRole(&apos;ADMIN&apos;) and hasRole(&apos;DBA&apos;)&quot;/&gt;</span><br><span class="line">        &lt;form-login login-page=&quot;/login&quot;</span><br><span class="line">                    username-parameter=&quot;ssoId&quot;</span><br><span class="line">                    password-parameter=&quot;password&quot;</span><br><span class="line">                    authentication-failure-url=&quot;/Access_Denied&quot;</span><br><span class="line">                    /&gt;</span><br><span class="line">        &lt;csrf/&gt;</span><br><span class="line"></span><br><span class="line">        &lt;remember-me</span><br><span class="line">                remember-me-parameter=&quot;remember-me&quot;</span><br><span class="line">                remember-me-cookie=&quot;remember-me&quot;</span><br><span class="line">                token-validity-seconds=&quot;86400&quot;</span><br><span class="line">                data-source-ref=&quot;dataSource&quot; /&gt;</span><br><span class="line">    &lt;/http&gt;</span><br><span class="line"></span><br><span class="line">    &lt;authentication-manager &gt;</span><br><span class="line">        &lt;authentication-provider user-service-ref=&quot;customUserDetailsService&quot;&gt;</span><br><span class="line"></span><br><span class="line">        &lt;/authentication-provider&gt;</span><br><span class="line"></span><br><span class="line">    &lt;/authentication-manager&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &lt;beans:bean id=&quot;customUserDetailsService&quot; class=&quot;com.anlu.secrity.service.impl.CustomUserDetailsService&quot; /&gt;</span><br><span class="line"></span><br><span class="line">&lt;/beans:beans&gt;</span><br></pre></td></tr></table></figure>
<h4 id="第六步：定义CustomUserDetailsService"><a href="#第六步：定义CustomUserDetailsService" class="headerlink" title="第六步：定义CustomUserDetailsService"></a>第六步：定义CustomUserDetailsService</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.service.impl;</span><br><span class="line"></span><br><span class="line">import com.anlu.secrity.model.User;</span><br><span class="line">import com.anlu.secrity.model.UserProfile;</span><br><span class="line">import com.anlu.secrity.service.UserService;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.security.core.GrantedAuthority;</span><br><span class="line">import org.springframework.security.core.authority.SimpleGrantedAuthority;</span><br><span class="line">import org.springframework.security.core.userdetails.UserDetails;</span><br><span class="line">import org.springframework.security.core.userdetails.UserDetailsService;</span><br><span class="line">import org.springframework.security.core.userdetails.UsernameNotFoundException;</span><br><span class="line">import org.springframework.transaction.annotation.Transactional;</span><br><span class="line"></span><br><span class="line">import java.util.ArrayList;</span><br><span class="line">import java.util.List;</span><br><span class="line"></span><br><span class="line">public class CustomUserDetailsService implements UserDetailsService&#123;</span><br><span class="line">    @Autowired</span><br><span class="line">    private UserService userService;</span><br><span class="line"></span><br><span class="line">    @Transactional(readOnly=true)</span><br><span class="line">    public UserDetails loadUserByUsername(String ssoId)</span><br><span class="line">            throws UsernameNotFoundException &#123;</span><br><span class="line">        User user = userService.findBySso(ssoId);</span><br><span class="line">        System.out.println(&quot;User : &quot;+user);</span><br><span class="line">        if(user==null)&#123;</span><br><span class="line">            System.out.println(&quot;User not found&quot;);</span><br><span class="line">            throw new UsernameNotFoundException(&quot;Username not found&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        return new org.springframework.security.core.userdetails.User(user.getSsoId(), user.getPassword(),</span><br><span class="line">                user.getState().equals(&quot;Active&quot;), true, true, true, getGrantedAuthorities(user));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    private List&lt;GrantedAuthority&gt; getGrantedAuthorities(User user)&#123;</span><br><span class="line">        List&lt;GrantedAuthority&gt; authorities = new ArrayList&lt;GrantedAuthority&gt;();</span><br><span class="line"></span><br><span class="line">        for(UserProfile userProfile : user.getUserProfiles())&#123;</span><br><span class="line">            System.out.println(&quot;UserProfile : &quot;+userProfile);</span><br><span class="line">//            authorities.add(new SimpleGrantedAuthority(userProfile.getType()));</span><br><span class="line">            authorities.add(new SimpleGrantedAuthority(&quot;ROLE_&quot;+userProfile.getType()));</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">        System.out.print(&quot;authorities :&quot;+authorities);</span><br><span class="line">        return authorities;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="Hibernate配置部分"><a href="#Hibernate配置部分" class="headerlink" title="Hibernate配置部分"></a>Hibernate配置部分</h2><p>Hibernate配置类包含数据源层，SessionFactory和事务管理的@Bean方法。数据源属性是取自 application.properties 文件，包含MySQL数据库详细连接信息。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.config;</span><br><span class="line"></span><br><span class="line">import org.hibernate.SessionFactory;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.context.annotation.Bean;</span><br><span class="line">import org.springframework.context.annotation.Configuration;</span><br><span class="line">import org.springframework.context.annotation.PropertySource;</span><br><span class="line">import org.springframework.core.env.Environment;</span><br><span class="line">import org.springframework.jdbc.datasource.DriverManagerDataSource;</span><br><span class="line">import org.springframework.orm.hibernate4.HibernateTransactionManager;</span><br><span class="line">import org.springframework.orm.hibernate4.LocalSessionFactoryBean;</span><br><span class="line">import org.springframework.transaction.annotation.EnableTransactionManagement;</span><br><span class="line"></span><br><span class="line">import javax.sql.DataSource;</span><br><span class="line">import java.util.Properties;</span><br><span class="line"></span><br><span class="line">@Configuration</span><br><span class="line">@EnableTransactionManagement</span><br><span class="line">@PropertySource(value = &#123; &quot;classpath:application.properties&quot; &#125;)</span><br><span class="line">public class HibernateConfiguration &#123;</span><br><span class="line">    @Autowired</span><br><span class="line">    private Environment environment;</span><br><span class="line"></span><br><span class="line">    @Bean</span><br><span class="line">    public LocalSessionFactoryBean sessionFactory() &#123;</span><br><span class="line">        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();</span><br><span class="line">        sessionFactory.setDataSource(dataSource());</span><br><span class="line">        sessionFactory.setPackagesToScan(new String[] &#123; &quot;com.anlu.secrity.model&quot; &#125;);</span><br><span class="line">        sessionFactory.setHibernateProperties(hibernateProperties());</span><br><span class="line">        return sessionFactory;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Bean</span><br><span class="line">    public DataSource dataSource() &#123;</span><br><span class="line">        DriverManagerDataSource dataSource = new DriverManagerDataSource();</span><br><span class="line">        dataSource.setDriverClassName(environment.getRequiredProperty(&quot;jdbc.driverClassName&quot;));</span><br><span class="line">        dataSource.setUrl(environment.getRequiredProperty(&quot;jdbc.url&quot;));</span><br><span class="line">        dataSource.setUsername(environment.getRequiredProperty(&quot;jdbc.username&quot;));</span><br><span class="line">        dataSource.setPassword(environment.getRequiredProperty(&quot;jdbc.password&quot;));</span><br><span class="line">        return dataSource;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    private Properties hibernateProperties() &#123;</span><br><span class="line">        Properties properties = new Properties();</span><br><span class="line">        properties.put(&quot;hibernate.dialect&quot;, environment.getRequiredProperty(&quot;hibernate.dialect&quot;));</span><br><span class="line">        properties.put(&quot;hibernate.show_sql&quot;, environment.getRequiredProperty(&quot;hibernate.show_sql&quot;));</span><br><span class="line">        properties.put(&quot;hibernate.format_sql&quot;, environment.getRequiredProperty(&quot;hibernate.format_sql&quot;));</span><br><span class="line">        return properties;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Bean</span><br><span class="line">    @Autowired</span><br><span class="line">    public HibernateTransactionManager transactionManager(SessionFactory s) &#123;</span><br><span class="line">        HibernateTransactionManager txManager = new HibernateTransactionManager();</span><br><span class="line">        txManager.setSessionFactory(s);</span><br><span class="line">        return txManager;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>application.properties</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">jdbc.driverClassName = com.mysql.jdbc.Driver</span><br><span class="line">jdbc.url = jdbc:mysql://localhost:3306/yiibai</span><br><span class="line">jdbc.username = myuser</span><br><span class="line">jdbc.password = mypassword</span><br><span class="line">hibernate.dialect = org.hibernate.dialect.MySQLDialect</span><br><span class="line">hibernate.show_sql = true</span><br><span class="line">hibernate.format_sql = true</span><br></pre></td></tr></table></figure>
<h2 id="DAO-Model-amp-Service服务"><a href="#DAO-Model-amp-Service服务" class="headerlink" title="DAO, Model &amp; Service服务"></a>DAO, Model &amp; Service服务</h2><h4 id="第4步-创建模型类"><a href="#第4步-创建模型类" class="headerlink" title="第4步: 创建模型类"></a>第4步: 创建模型类</h4><p>用户可以有多个角色[DBA，ADMIN，USER]。而角色可以被分配给一个以上的用户。因此，有一个用户和用户配置[角色]之间存在多对多的关系。我们保持这种关系单向[用户到用户配置]，因为我们只是在查找对于给用户的角色。我们将使用使用连接表来实现多一对多关联。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.model;</span><br><span class="line"></span><br><span class="line">import org.hibernate.validator.constraints.NotEmpty;</span><br><span class="line"></span><br><span class="line">import javax.persistence.*;</span><br><span class="line">import java.util.HashSet;</span><br><span class="line">import java.util.Set;</span><br><span class="line"></span><br><span class="line">@Entity</span><br><span class="line">@Table(name=&quot;APP_USER&quot;)</span><br><span class="line">public class User &#123;</span><br><span class="line">    @Id</span><br><span class="line">    @GeneratedValue(strategy= GenerationType.IDENTITY)</span><br><span class="line">    private int id;</span><br><span class="line"></span><br><span class="line">    @NotEmpty</span><br><span class="line">    @Column(name=&quot;SSO_ID&quot;, unique=true, nullable=false)</span><br><span class="line">    private String ssoId;</span><br><span class="line"></span><br><span class="line">    @NotEmpty</span><br><span class="line">    @Column(name=&quot;PASSWORD&quot;, nullable=false)</span><br><span class="line">    private String password;</span><br><span class="line"></span><br><span class="line">    @NotEmpty</span><br><span class="line">    @Column(name=&quot;FIRST_NAME&quot;, nullable=false)</span><br><span class="line">    private String firstName;</span><br><span class="line"></span><br><span class="line">    @NotEmpty</span><br><span class="line">    @Column(name=&quot;LAST_NAME&quot;, nullable=false)</span><br><span class="line">    private String lastName;</span><br><span class="line"></span><br><span class="line">    @NotEmpty</span><br><span class="line">    @Column(name=&quot;EMAIL&quot;, nullable=false)</span><br><span class="line">    private String email;</span><br><span class="line"></span><br><span class="line">    @NotEmpty</span><br><span class="line">    @Column(name=&quot;STATE&quot;, nullable=false)</span><br><span class="line">    private String state=State.ACTIVE.getState();</span><br><span class="line"></span><br><span class="line">    @ManyToMany(fetch = FetchType.EAGER)</span><br><span class="line">    @JoinTable(name = &quot;APP_USER_USER_PROFILE&quot;,</span><br><span class="line">            joinColumns = &#123; @JoinColumn(name = &quot;USER_ID&quot;) &#125;,</span><br><span class="line">            inverseJoinColumns = &#123; @JoinColumn(name = &quot;USER_PROFILE_ID&quot;) &#125;)</span><br><span class="line">    private Set&lt;UserProfile&gt; userProfiles = new HashSet&lt;UserProfile&gt;();</span><br><span class="line"></span><br><span class="line">    public int getId() &#123;</span><br><span class="line">        return id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setId(int id) &#123;</span><br><span class="line">        this.id = id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getSsoId() &#123;</span><br><span class="line">        return ssoId;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setSsoId(String ssoId) &#123;</span><br><span class="line">        this.ssoId = ssoId;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getPassword() &#123;</span><br><span class="line">        return password;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setPassword(String password) &#123;</span><br><span class="line">        this.password = password;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getFirstName() &#123;</span><br><span class="line">        return firstName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setFirstName(String firstName) &#123;</span><br><span class="line">        this.firstName = firstName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getLastName() &#123;</span><br><span class="line">        return lastName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setLastName(String lastName) &#123;</span><br><span class="line">        this.lastName = lastName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getEmail() &#123;</span><br><span class="line">        return email;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setEmail(String email) &#123;</span><br><span class="line">        this.email = email;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getState() &#123;</span><br><span class="line">        return state;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setState(String state) &#123;</span><br><span class="line">        this.state = state;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public Set&lt;UserProfile&gt; getUserProfiles() &#123;</span><br><span class="line">        return userProfiles;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setUserProfiles(Set&lt;UserProfile&gt; userProfiles) &#123;</span><br><span class="line">        this.userProfiles = userProfiles;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public int hashCode() &#123;</span><br><span class="line">        final int prime = 31;</span><br><span class="line">        int result = 1;</span><br><span class="line">        result = prime * result + id;</span><br><span class="line">        result = prime * result + ((ssoId == null) ? 0 : ssoId.hashCode());</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public boolean equals(Object obj) &#123;</span><br><span class="line">        if (this == obj)</span><br><span class="line">            return true;</span><br><span class="line">        if (obj == null)</span><br><span class="line">            return false;</span><br><span class="line">        if (!(obj instanceof User))</span><br><span class="line">            return false;</span><br><span class="line">        User other = (User) obj;</span><br><span class="line">        if (id != other.id)</span><br><span class="line">            return false;</span><br><span class="line">        if (ssoId == null) &#123;</span><br><span class="line">            if (other.ssoId != null)</span><br><span class="line">                return false;</span><br><span class="line">        &#125; else if (!ssoId.equals(other.ssoId))</span><br><span class="line">            return false;</span><br><span class="line">        return true;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public String toString() &#123;</span><br><span class="line">        return &quot;User [id=&quot; + id + &quot;, ssoId=&quot; + ssoId + &quot;, password=&quot; + password</span><br><span class="line">                + &quot;, firstName=&quot; + firstName + &quot;, lastName=&quot; + lastName</span><br><span class="line">                + &quot;, email=&quot; + email + &quot;, state=&quot; + state + &quot;, userProfiles=&quot; + userProfiles +&quot;]&quot;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.model;</span><br><span class="line"></span><br><span class="line">import javax.persistence.*;</span><br><span class="line"></span><br><span class="line">@Entity</span><br><span class="line">@Table(name=&quot;USER_PROFILE&quot;)</span><br><span class="line">public class UserProfile &#123;</span><br><span class="line">    @Id</span><br><span class="line">    @GeneratedValue(strategy= GenerationType.IDENTITY)</span><br><span class="line">    private int id;</span><br><span class="line"></span><br><span class="line">    @Column(name=&quot;TYPE&quot;, length=15, unique=true, nullable=false)</span><br><span class="line">    private String type = UserProfileType.USER.getUserProfileType();</span><br><span class="line"></span><br><span class="line">    public int getId() &#123;</span><br><span class="line">        return id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setId(int id) &#123;</span><br><span class="line">        this.id = id;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getType() &#123;</span><br><span class="line">        return type;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setType(String type) &#123;</span><br><span class="line">        this.type = type;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public int hashCode() &#123;</span><br><span class="line">        final int prime = 31;</span><br><span class="line">        int result = 1;</span><br><span class="line">        result = prime * result + id;</span><br><span class="line">        result = prime * result + ((type == null) ? 0 : type.hashCode());</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public boolean equals(Object obj) &#123;</span><br><span class="line">        if (this == obj)</span><br><span class="line">            return true;</span><br><span class="line">        if (obj == null)</span><br><span class="line">            return false;</span><br><span class="line">        if (!(obj instanceof UserProfile))</span><br><span class="line">            return false;</span><br><span class="line">        UserProfile other = (UserProfile) obj;</span><br><span class="line">        if (id != other.id)</span><br><span class="line">            return false;</span><br><span class="line">        if (type == null) &#123;</span><br><span class="line">            if (other.type != null)</span><br><span class="line">                return false;</span><br><span class="line">        &#125; else if (!type.equals(other.type))</span><br><span class="line">            return false;</span><br><span class="line">        return true;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public String toString() &#123;</span><br><span class="line">        return &quot;UserProfile [id=&quot; + id + &quot;,  type=&quot; + type	+ &quot;]&quot;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.model;</span><br><span class="line"></span><br><span class="line">public enum UserProfileType &#123;</span><br><span class="line">    USER(&quot;USER&quot;),</span><br><span class="line">    DBA(&quot;DBA&quot;),</span><br><span class="line">    ADMIN(&quot;ADMIN&quot;);</span><br><span class="line"></span><br><span class="line">    String userProfileType;</span><br><span class="line"></span><br><span class="line">    private UserProfileType(String userProfileType)&#123;</span><br><span class="line">        this.userProfileType = userProfileType;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getUserProfileType()&#123;</span><br><span class="line">        return userProfileType;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.model;</span><br><span class="line"></span><br><span class="line">public enum State &#123;</span><br><span class="line">    ACTIVE(&quot;Active&quot;),</span><br><span class="line">    INACTIVE(&quot;Inactive&quot;),</span><br><span class="line">    DELETED(&quot;Deleted&quot;),</span><br><span class="line">    LOCKED(&quot;Locked&quot;);</span><br><span class="line"></span><br><span class="line">    private String state;</span><br><span class="line"></span><br><span class="line">    private State(final String state)&#123;</span><br><span class="line">        this.state = state;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public String getState()&#123;</span><br><span class="line">        return this.state;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public String toString()&#123;</span><br><span class="line">        return this.state;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    public String getName()&#123;</span><br><span class="line">        return this.name();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="第5步-创建-Dao-层"><a href="#第5步-创建-Dao-层" class="headerlink" title="第5步: 创建 Dao 层"></a>第5步: 创建 Dao 层</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.dao;</span><br><span class="line"></span><br><span class="line">import org.hibernate.Criteria;</span><br><span class="line">import org.hibernate.Session;</span><br><span class="line">import org.hibernate.SessionFactory;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"></span><br><span class="line">import java.io.Serializable;</span><br><span class="line">import java.lang.reflect.ParameterizedType;</span><br><span class="line"></span><br><span class="line">public abstract class AbstractDao&lt;PK extends Serializable,T&gt; &#123;</span><br><span class="line">    private final Class&lt;T&gt; persistentClass;</span><br><span class="line">    @SuppressWarnings(&quot;unchecked&quot;)</span><br><span class="line">    public AbstractDao()&#123;</span><br><span class="line">        this.persistentClass =(Class&lt;T&gt;) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    private SessionFactory sessionFactory;</span><br><span class="line"></span><br><span class="line">    protected Session getSession()&#123;</span><br><span class="line">        return sessionFactory.getCurrentSession();</span><br><span class="line">    &#125;</span><br><span class="line">    @SuppressWarnings(&quot;unchecked&quot;)</span><br><span class="line">    public T getByKey(PK key) &#123;</span><br><span class="line">        return (T) getSession().get(persistentClass, key);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void persist(T entity)&#123;</span><br><span class="line">        getSession().persist(entity);</span><br><span class="line">    &#125;</span><br><span class="line">    public void delete(T entity) &#123;</span><br><span class="line">        getSession().delete(entity);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    protected Criteria createEntityCriteria()&#123;</span><br><span class="line">        return getSession().createCriteria(persistentClass);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.dao;</span><br><span class="line"></span><br><span class="line">import com.anlu.secrity.model.User;</span><br><span class="line"></span><br><span class="line">public interface UserDao &#123;</span><br><span class="line">    void save(User user);</span><br><span class="line"></span><br><span class="line">    User findById(int id);</span><br><span class="line"></span><br><span class="line">    User findBySSO(String sso);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.dao.impl;</span><br><span class="line"></span><br><span class="line">import com.anlu.secrity.dao.AbstractDao;</span><br><span class="line">import com.anlu.secrity.dao.UserDao;</span><br><span class="line">import com.anlu.secrity.model.User;</span><br><span class="line">import org.hibernate.Criteria;</span><br><span class="line">import org.hibernate.criterion.Restrictions;</span><br><span class="line">import org.springframework.stereotype.Repository;</span><br><span class="line"></span><br><span class="line">@Repository</span><br><span class="line">public class UserDaoImpl extends AbstractDao&lt;Integer, User&gt; implements UserDao &#123;</span><br><span class="line">    public void save(User user) &#123;</span><br><span class="line">        persist(user);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public User findById(int id) &#123;</span><br><span class="line">        return findById(id);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public User findBySSO(String sso) &#123;</span><br><span class="line">        Criteria crit = createEntityCriteria();</span><br><span class="line">        crit.add(Restrictions.eq(&quot;ssoId&quot;, sso));</span><br><span class="line">        return (User) crit.uniqueResult();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="第6步-创建Service层"><a href="#第6步-创建Service层" class="headerlink" title="第6步: 创建Service层"></a>第6步: 创建Service层</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.service;</span><br><span class="line"></span><br><span class="line">import com.anlu.secrity.model.User;</span><br><span class="line"></span><br><span class="line">public interface UserService &#123;</span><br><span class="line">    void save(User user);</span><br><span class="line"></span><br><span class="line">    User findById(int id);</span><br><span class="line"></span><br><span class="line">    User findBySso(String sso);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.service.impl;</span><br><span class="line"></span><br><span class="line">import com.anlu.secrity.dao.UserDao;</span><br><span class="line">import com.anlu.secrity.model.User;</span><br><span class="line">import com.anlu.secrity.service.UserService;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;</span><br><span class="line">import org.springframework.stereotype.Service;</span><br><span class="line">import org.springframework.transaction.annotation.Transactional;</span><br><span class="line"></span><br><span class="line">@Service</span><br><span class="line">@Transactional</span><br><span class="line">public class UserServiceImpl implements UserService &#123;</span><br><span class="line">    @Autowired</span><br><span class="line">    private UserDao dao;</span><br><span class="line"></span><br><span class="line">    public void save(User user) &#123;</span><br><span class="line">        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();</span><br><span class="line">//        System.out.println(passwordEncoder.encode(password));</span><br><span class="line">        user.setPassword(passwordEncoder.encode(user.getPassword()));</span><br><span class="line">        dao.save(user);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public User findById(int id) &#123;</span><br><span class="line">        return dao.findById(id);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public User findBySso(String sso) &#123;</span><br><span class="line">        return dao.findBySSO(sso);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="Controller控制器"><a href="#Controller控制器" class="headerlink" title="Controller控制器"></a>Controller控制器</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line">package com.anlu.secrity.controller;</span><br><span class="line"></span><br><span class="line">import org.springframework.security.core.Authentication;</span><br><span class="line">import org.springframework.security.core.context.SecurityContextHolder;</span><br><span class="line">import org.springframework.security.core.userdetails.UserDetails;</span><br><span class="line">import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;</span><br><span class="line"></span><br><span class="line">import org.springframework.stereotype.Controller;</span><br><span class="line">import org.springframework.ui.ModelMap;</span><br><span class="line">import org.springframework.web.bind.annotation.RequestMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.RequestMethod;</span><br><span class="line">import org.springframework.web.servlet.ModelAndView;</span><br><span class="line"></span><br><span class="line">import javax.servlet.http.HttpServletRequest;</span><br><span class="line">import javax.servlet.http.HttpServletResponse;</span><br><span class="line"></span><br><span class="line">@Controller</span><br><span class="line">public class HelloController &#123;</span><br><span class="line"></span><br><span class="line">    @RequestMapping(value = &quot;/hello&quot;)</span><br><span class="line">    public ModelAndView tohello()&#123;</span><br><span class="line">        ModelAndView mv = new ModelAndView();</span><br><span class="line">        mv.setViewName(&quot;hello&quot;);</span><br><span class="line">        return mv;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @RequestMapping(value = &#123; &quot;/&quot;, &quot;/home&quot; &#125;, method = RequestMethod.GET)</span><br><span class="line">    public String homePage(ModelMap model) &#123;</span><br><span class="line">        model.addAttribute(&quot;greeting&quot;, &quot;Hi, Welcome to mysite&quot;);</span><br><span class="line">        return &quot;welcome&quot;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @RequestMapping(value = &quot;/admin&quot;, method = RequestMethod.GET)</span><br><span class="line">    public String adminPage(ModelMap model) &#123;</span><br><span class="line">        model.addAttribute(&quot;user&quot;, getPrincipal());</span><br><span class="line">        return &quot;admin&quot;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @RequestMapping(value = &quot;/dba&quot;, method = RequestMethod.GET)</span><br><span class="line">    public String dbaPage(ModelMap model) &#123;</span><br><span class="line">        model.addAttribute(&quot;user&quot;, getPrincipal());</span><br><span class="line">        return &quot;dba&quot;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @RequestMapping(value = &quot;/Access_Denied&quot;, method = RequestMethod.GET)</span><br><span class="line">    public String accessDeniedPage(ModelMap model) &#123;</span><br><span class="line">        model.addAttribute(&quot;user&quot;, getPrincipal());</span><br><span class="line">        return &quot;accessDenied&quot;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @RequestMapping(value = &quot;/login&quot;, method = RequestMethod.GET)</span><br><span class="line">    public String loginPage() &#123;</span><br><span class="line">        return &quot;login&quot;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @RequestMapping(value=&quot;/logout&quot;, method = RequestMethod.GET)</span><br><span class="line">    public String logoutPage (HttpServletRequest request, HttpServletResponse response) &#123;</span><br><span class="line">        Authentication auth = SecurityContextHolder.getContext().getAuthentication();</span><br><span class="line">        if (auth != null)&#123;</span><br><span class="line">            new SecurityContextLogoutHandler().logout(request, response, auth);</span><br><span class="line">        &#125;</span><br><span class="line">        return &quot;redirect:/login?logout&quot;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    private String getPrincipal()&#123;</span><br><span class="line">        String userName = null;</span><br><span class="line">        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();</span><br><span class="line"></span><br><span class="line">        if (principal instanceof UserDetails) &#123;</span><br><span class="line">            userName = ((UserDetails)principal).getUsername();</span><br><span class="line">        &#125; else &#123;</span><br><span class="line">            userName = principal.toString();</span><br><span class="line">        &#125;</span><br><span class="line">        return userName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="视图部分"><a href="#视图部分" class="headerlink" title="视图部分"></a>视图部分</h2><p>login.jsp</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><span class="line">&lt;%--</span><br><span class="line">  Created by IntelliJ IDEA.</span><br><span class="line">  User: Anlu</span><br><span class="line">  Date: 2018/1/1</span><br><span class="line">  Time: 18:56</span><br><span class="line">  To change this template use File | Settings | File Templates.</span><br><span class="line">--%&gt;</span><br><span class="line">&lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&gt;</span><br><span class="line">&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">    &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&gt;</span><br><span class="line">    &lt;title&gt;HelloWorld Login page&lt;/title&gt;</span><br><span class="line">    &lt;link href=&quot;lib/bootstrap/css/bootstrap.css&quot;  rel=&quot;stylesheet&quot;&gt;&lt;/link&gt;</span><br><span class="line">    &lt;link href=&quot;&lt;c:url value=&apos;/static/css/app.css&apos; /&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;/link&gt;</span><br><span class="line">    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.css&quot; /&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line"></span><br><span class="line">&lt;body&gt;</span><br><span class="line">&lt;div id=&quot;mainWrapper&quot;&gt;</span><br><span class="line">    &lt;div class=&quot;login-container&quot;&gt;</span><br><span class="line">        &lt;div class=&quot;login-card&quot;&gt;</span><br><span class="line">            &lt;div class=&quot;login-form&quot;&gt;</span><br><span class="line">                &lt;c:url var=&quot;loginUrl&quot; value=&quot;/login&quot; /&gt;</span><br><span class="line">                &lt;form action=&quot;$&#123;loginUrl&#125;&quot; method=&quot;post&quot; class=&quot;form-horizontal&quot;&gt;</span><br><span class="line">                    &lt;c:if test=&quot;$&#123;param.error != null&#125;&quot;&gt;</span><br><span class="line">                        &lt;div class=&quot;alert alert-danger&quot;&gt;</span><br><span class="line">                            &lt;p&gt;Invalid username and password.&lt;/p&gt;</span><br><span class="line">                        &lt;/div&gt;</span><br><span class="line">                    &lt;/c:if&gt;</span><br><span class="line">                    &lt;c:if test=&quot;$&#123;param.logout != null&#125;&quot;&gt;</span><br><span class="line">                        &lt;div class=&quot;alert alert-success&quot;&gt;</span><br><span class="line">                            &lt;p&gt;You have been logged out successfully.&lt;/p&gt;</span><br><span class="line">                        &lt;/div&gt;</span><br><span class="line">                    &lt;/c:if&gt;</span><br><span class="line">                    &lt;div class=&quot;input-group input-sm&quot;&gt;</span><br><span class="line">                        &lt;label class=&quot;input-group-addon&quot; for=&quot;username&quot;&gt;&lt;i class=&quot;fa fa-user&quot;&gt;&lt;/i&gt;&lt;/label&gt;</span><br><span class="line">                        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;username&quot; name=&quot;ssoId&quot; placeholder=&quot;Enter Username&quot; required&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                    &lt;div class=&quot;input-group input-sm&quot;&gt;</span><br><span class="line">                        &lt;label class=&quot;input-group-addon&quot; for=&quot;password&quot;&gt;&lt;i class=&quot;fa fa-lock&quot;&gt;&lt;/i&gt;&lt;/label&gt;</span><br><span class="line">                        &lt;input type=&quot;password&quot; class=&quot;form-control&quot; id=&quot;password&quot; name=&quot;password&quot; placeholder=&quot;Enter Password&quot; required&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                    &lt;div class=&quot;input-group input-sm&quot;&gt;</span><br><span class="line">                        &lt;div class=&quot;checkbox&quot;&gt;</span><br><span class="line">                            &lt;label&gt;&lt;input type=&quot;checkbox&quot; id=&quot;rememberme&quot; name=&quot;remember-me&quot;&gt; Remember Me&lt;/label&gt;</span><br><span class="line">                        &lt;/div&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                    &lt;input type=&quot;hidden&quot; name=&quot;$&#123;_csrf.parameterName&#125;&quot;</span><br><span class="line">                           value=&quot;$&#123;_csrf.token&#125;&quot; /&gt;</span><br><span class="line"></span><br><span class="line">                    &lt;div class=&quot;form-actions&quot;&gt;</span><br><span class="line">                        &lt;input type=&quot;submit&quot;</span><br><span class="line">                               class=&quot;btn btn-block btn-primary btn-default&quot; value=&quot;Log in&quot;&gt;</span><br><span class="line">                    &lt;/div&gt;</span><br><span class="line">                &lt;/form&gt;</span><br><span class="line">            &lt;/div&gt;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<p>如你所看到的，CSRF参数需要在JSP中的EL表达式访问，所以还需要通过添将以下的代码添加JSP的顶部来强行执行EL表达式解析编译：</p>
<p>admin.jsp</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&gt;</span><br><span class="line">&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;</span><br><span class="line">&lt;%@ taglib prefix=&quot;sec&quot; uri=&quot;http://www.springframework.org/security/tags&quot;%&gt;</span><br><span class="line"></span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&gt;</span><br><span class="line">	&lt;title&gt;Admin page&lt;/title&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">	Dear &lt;strong&gt;$&#123;user&#125;&lt;/strong&gt;, Welcome to Admin Page.</span><br><span class="line">	</span><br><span class="line">	&lt;sec:authorize access=&quot;isFullyAuthenticated()&quot;&gt;</span><br><span class="line">		&lt;label&gt;&lt;a href=&quot;#&quot;&gt;Create New User&lt;/a&gt; | &lt;a href=&quot;#&quot;&gt;View existing Users&lt;/a&gt;&lt;/label&gt;</span><br><span class="line">	&lt;/sec:authorize&gt;</span><br><span class="line">	&lt;sec:authorize access=&quot;isRememberMe()&quot;&gt;</span><br><span class="line">		&lt;label&gt;&lt;a href=&quot;#&quot;&gt;View existing Users&lt;/a&gt;&lt;/label&gt;</span><br><span class="line">	&lt;/sec:authorize&gt;</span><br><span class="line"> </span><br><span class="line">	&lt;a href=&quot;&lt;c:url value=&quot;/logout&quot; /&gt;&quot;&gt;Logout&lt;/a&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<p>welcome.jsp</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&gt;</span><br><span class="line">&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&gt;</span><br><span class="line">	&lt;title&gt;Welcome page&lt;/title&gt;</span><br><span class="line">	&lt;link href=&quot;&lt;c:url value=&apos;/static/css/bootstrap.css&apos; /&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;/link&gt;</span><br><span class="line">	&lt;link href=&quot;&lt;c:url value=&apos;/static/css/app.css&apos; /&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;/link&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">	&lt;div class=&quot;success&quot;&gt;</span><br><span class="line">		Greeting : $&#123;greeting&#125;</span><br><span class="line">		This is a welcome page.</span><br><span class="line">	&lt;/div&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<p>dba.jsp</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot;  pageEncoding=&quot;ISO-8859-1&quot;%&gt;</span><br><span class="line">&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&gt;</span><br><span class="line">&lt;title&gt;DBA page&lt;/title&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">	Dear &lt;strong&gt;$&#123;user&#125;&lt;/strong&gt;, Welcome to DBA Page.</span><br><span class="line">	&lt;a href=&quot;&lt;c:url value=&quot;/logout&quot; /&gt;&quot;&gt;Logout&lt;/a&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<p>accessDenied.jsp</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&gt;</span><br><span class="line">&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot;%&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=ISO-8859-1&quot;&gt;</span><br><span class="line">	&lt;title&gt;AccessDenied page&lt;/title&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">	Dear &lt;strong&gt;$&#123;user&#125;&lt;/strong&gt;, You are not authorized to access this page</span><br><span class="line">	&lt;a href=&quot;&lt;c:url value=&quot;/logout&quot; /&gt;&quot;&gt;Logout&lt;/a&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<h2 id="运行程序"><a href="#运行程序" class="headerlink" title="运行程序"></a>运行程序</h2><p>打开浏览器并访问 -  <a href="http://localhost:8080/SpringSecurityRememberMeAnnotation/admin" target="_blank" rel="noopener">http://localhost:8080/SpringSecurityRememberMeAnnotation/admin</a></p>
<p>系统将提示您登录，如下图中所示 - </p>
<p><img src="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104215329.png" alt="2"></p>
<p>使用”记住我” 验证登录(使用用户：anlu/111111)，您将获得管理员视图，如下所示 - </p>
<p>验证查看 Cookies。打开谷歌浏览器设置/显示高级设置/内容设置/所有Cookie和网站数据显示本地主机。你会发现有两个 cookies ，一个用于当前会话[JSESSIONID]，一个用于”记住我”的身份验证。</p>
<p><img src="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104215306.png" alt="1"></p>
<p>点击”记住我”(remember-me)，查看cookie详细信息。你可以看到 cookie 的有效期是一天(如在安全配置设置)。</p>
<p>现在查看 persistent_logins 表中数据。应该有当前用户的 Cookies 记录信息。</p>
<p>数据库中多了一条信息</p>
<p><img src="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104215934.png" alt="2"></p>
<p>现在退出登录，如下图中所示  - </p>
<p><img src="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104220056.png" alt="4"></p>
<p>现在再试尝试打开：<a href="http://localhost:8080/SpringSecurityRememberMeAnnotation/admin，应该直接登录，而不再需要使用输入用户名和密码登录。" target="_blank" rel="noopener">http://localhost:8080/SpringSecurityRememberMeAnnotation/admin，应该直接登录，而不再需要使用输入用户名和密码登录。</a></p>
<p><img src="http://p1aoqp63y.bkt.clouddn.com/QQ%E6%88%AA%E5%9B%BE20180104220206.png" alt="2"></p>
<p>还可以看到 “Create New User” 选项不可用，这是因为一个是仅当用户(使用登录名/密码，例如)有权限的认证才能使用此功能，现在从Chrome中删除 “记住我” 的cookie(如前所示)，并再次尝试访问：<a href="http://localhost:8080/SpringSecurityRememberMeAnnotation/admin" target="_blank" rel="noopener">http://localhost:8080/SpringSecurityRememberMeAnnotation/admin</a>，程序应该提示您登录。</p>
<h2 id="下载地址"><a href="#下载地址" class="headerlink" title="下载地址"></a>下载地址</h2><p><a href="https://github.com/Spring-Secrity/Spring-secrity-rememberme/archive/master.zip" target="_blank" rel="noopener"><strong>Spring-secrity-rememberme</strong></a></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2018/10/12/2018-01-21-Spring-secrity-rememberme-annotaion/" data-id="cjoztxu1i00011wijmjcaokxj" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/org/tags/spring-secrity/">spring-secrity</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/org/2018/10/12/2018-06-17-SpringBoot web开发-Freemaker模板引擎/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          SpringBoot web开发-Freemaker模板引擎
        
      </div>
    </a>
  
  
    <a href="/org/2018/10/12/2018-06-15-Jenkins持续集成入门篇/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">Jenkins继续集成入门</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/SVN/">SVN</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/Spring-secrity/">Spring-secrity</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/hexo/">hexo</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/hibenrate/">hibenrate</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/jekyll/">jekyll</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/jenkins/">jenkins</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/redis/">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/shiro/">shiro</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/spingMVC/">spingMVC</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/spring-cloud/">spring cloud</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/spring-cloud/">spring-cloud</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/spring-secrity/">spring-secrity</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/springMVC/">springMVC</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/springboot/">springboot</a></li><li class="tag-list-item"><a class="tag-list-link" href="/org/tags/生活/">生活</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/org/tags/SVN/" style="font-size: 12px;">SVN</a> <a href="/org/tags/Spring-secrity/" style="font-size: 10px;">Spring-secrity</a> <a href="/org/tags/hexo/" style="font-size: 10px;">hexo</a> <a href="/org/tags/hibenrate/" style="font-size: 10px;">hibenrate</a> <a href="/org/tags/jekyll/" style="font-size: 10px;">jekyll</a> <a href="/org/tags/jenkins/" style="font-size: 10px;">jenkins</a> <a href="/org/tags/redis/" style="font-size: 16px;">redis</a> <a href="/org/tags/shiro/" style="font-size: 18px;">shiro</a> <a href="/org/tags/spingMVC/" style="font-size: 10px;">spingMVC</a> <a href="/org/tags/spring-cloud/" style="font-size: 10px;">spring cloud</a> <a href="/org/tags/spring-cloud/" style="font-size: 10px;">spring-cloud</a> <a href="/org/tags/spring-secrity/" style="font-size: 12px;">spring-secrity</a> <a href="/org/tags/springMVC/" style="font-size: 14px;">springMVC</a> <a href="/org/tags/springboot/" style="font-size: 20px;">springboot</a> <a href="/org/tags/生活/" style="font-size: 10px;">生活</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/org/archives/2018/11/">November 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/org/archives/2018/10/">October 2018</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/org/2018/11/27/redis07-zookeeper-kafka集群部署以及如何使用简单介绍/">redis07-zookeeper+kafka集群部署以及如何使用简单介绍</a>
          </li>
        
          <li>
            <a href="/org/2018/11/13/redis06-cluster实现高可用性/">redis06-cluster实现高可用性</a>
          </li>
        
          <li>
            <a href="/org/2018/11/12/redis05-在项目中搭建读写分-高可用-多master的redis-cluster集群/">redis05-在项目中搭建读写分+高可用+多master的redis cluster集群</a>
          </li>
        
          <li>
            <a href="/org/2018/11/05/在项目中用经典的三节点方式部署哨兵集群-笔记/">在项目中用经典的三节点方式部署哨兵集群-笔记</a>
          </li>
        
          <li>
            <a href="/org/2018/11/05/redis哨兵的多个核心底层原理-笔记/">redis哨兵的多个核心底层原理-笔记</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2018 John Doe<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/org/" class="mobile-nav-link">Home</a>
  
    <a href="/org/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//code.jquery.com/jquery-2.0.3.min.js"></script>


  <link rel="stylesheet" href="/org/fancybox/jquery.fancybox.css">
  <script src="/org/fancybox/jquery.fancybox.pack.js"></script>


<script src="/org/js/script.js"></script>



  </div>
</body>
</html>